/*
作者：甜甜猫
*/
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <FastLED.h>
#include <FastLED_NeoMatrix.h>
#include <Fonts/TomThumb.h>
#include <ESP8266WiFi.h>
//#include <ESP8266WebServer.h>
#include <FS.h>  
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESPAsyncTCP.h>
#include <Hash.h>

#define brightlight 80  //亮度，0-255
#define LED_Pin 4  //ws2512数据接口
//#define AP//ap模式
#define STA//sta模式
CRGB leds[256];    //为每个led创建缓冲区
FastLED_NeoMatrix* led;  //调用FastLED_NeoMatrix显示库

AsyncWebServer server(80);    // 建立网络服务器对象，该对象用于响应HTTP请求。监听端口（80）

bool isUpData = false;
String upData = "";

char displayData[8 * 8 * 3] = {};//8*8像素*3个rgb

#ifdef STA
const char* ssid = "...";// 连接WiFi的名称
const char* password = "struggle.";// 需要连接的WiFi密码
#endif // STA

#ifdef AP
const char* ssid = "testWifi";// 连接WiFi的名称
const char* password = "12345678";// 需要连接的WiFi密码
#endif // AP

int imgRgbData[8 * 8][3] = {};

void LEDinit() //led屏初始化
{
	led = new FastLED_NeoMatrix(leds , 32 , 8 , NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG);
	FastLED.addLeds<NEOPIXEL , LED_Pin>(leds , 256).setCorrection(TypicalLEDStrip);
	led->begin();  //led初始化
	led->setTextWrap(false);  //禁用字体旋转
	led->setBrightness(brightlight);  //设置亮度
	led->setFont(&TomThumb);  //设置字体
	led->clear();  //清除缓冲区
}

void setup()
{
	//Serial.begin(115200);
	LEDinit();

	Serial.begin(115200);          // 启动串口通讯
	Serial.println("");

#ifdef STA
	WiFi.begin(ssid , password);                  // 启动网络连接
	Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
	Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接

	int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
	while ( WiFi.status() != WL_CONNECTED )
	{      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
		delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
		Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
	}

	// WiFi连接成功后将通过串口监视器输出连接成功信息 
	Serial.println('\n');
	Serial.print("Connected to ");
	Serial.println(WiFi.SSID());              // 通过串口监视器输出连接的WiFi名称
	Serial.print("IP address:\t");
	Serial.println(WiFi.localIP());           // 通过串口监视器输出ESP8266-NodeMCU的IP
#endif // DEBUG

#ifdef AP
	WiFi.softAP(ssid , password);
	Serial.print("Access Point: ");    // 通过串口监视器输出信息
	Serial.println(ssid);              // 告知用户NodeMCU所建立的WiFi名
	Serial.print("IP address: ");      // 以及NodeMCU的IP地址
	Serial.println(WiFi.softAPIP());   // 通过调用WiFi.softAPIP()可以得到NodeMCU的IP地址
#endif // DEBUG

	if ( SPIFFS.begin() )
	{                       // 启动闪存文件系统
		Serial.println("SPIFFS Started.");
	} else
	{
		Serial.println("SPIFFS Failed to Start.");
	}

#ifdef STA
	AsyncStaticWebHandler* handler = &server.serveStatic("/" , SPIFFS , "/sta").setDefaultFile("index.html").setCacheControl("max-age=600");
#endif // STA
#ifdef AP
	AsyncStaticWebHandler* handler = &server.serveStatic("/" , SPIFFS , "/ap").setDefaultFile("index.html").setCacheControl("max-age=600");
#endif // AP
	handler->setAuthentication("admin" , "admin");
	server.onNotFound(handleUserRequet);      // 告知系统如何处理用户请求
	server.on("/updata" , HTTP_POST , updata);
	server.begin();                           // 启动网站服务
	Serial.println("HTTP server started");

	srand(millis());

	led->clear();

	for ( int i = 0; i < 64; i++ )
	{
		for ( int j = 0; j < 3; j++ )
		{
			displayData[i * 3 + j] = rand() % 255;
		}

	}

	for ( int i = 0; i < 64; i++ )
	{
		for ( int j = 0; j < 3; j++ )
		{
			led->drawPixel(i % 8 , i / 8 , displayData[i * 3 + j]);
		}

	}
	led->show();

}

void loop()
{
	//if ( isUpData )
	//{
	//	isUpData = false;
	//	//开始解析数据sweetCat
	//	Serial.print("获取到的更新数据");
	//	Serial.println(upData);
	//	int lastIndex = 0;//上一个@的位置
	//	int nextIndex = 0;//下一个@的位置
	//	int nowIndex = 0;//当前找打了几个@
	//	for ( int i = 0; i < upData.length(); i++ )
	//	{
	//		if ( upData[i] == '@' )
	//		{
	//			if ( nowIndex >= 64 )
	//			{
	//				Serial.print("err:数据长度错误,代码:");
	//				Serial.println(nowIndex);
	//				return;
	//			}
	//			nextIndex = i;
	//			//剪切字符串
	//			String data_temp = upData.substring(lastIndex , nextIndex);
	//			//保存上一个字符串的位置
	//			lastIndex = i + 1;
	//			//Serial.println(data_temp);
	//			//提取数据
	//			int r , g , b;
	//			r = data_temp.substring(0 , data_temp.indexOf(",")).toInt();
	//			g = data_temp.substring(data_temp.indexOf(",") + 1 , data_temp.lastIndexOf(",")).toInt();
	//			b = data_temp.substring(data_temp.lastIndexOf(",") + 1).toInt();
	//			/*Serial.print(r);
	//			Serial.print("\t");
	//			Serial.print(g);
	//			Serial.print("\t");
	//			Serial.println(b);*/
	//			//放入数组
	//			imgRgbData[nowIndex][0] = r;
	//			imgRgbData[nowIndex][1] = g;
	//			imgRgbData[nowIndex][2] = b;

	//			nowIndex++;//更新当前的位置
	//		}
	//	}
	//	for ( int i = 0; i < 63; i++ )
	//	{
	//		Serial.print(imgRgbData[i][0]);
	//		Serial.print("\t");
	//		Serial.print(imgRgbData[i][1]);
	//		Serial.print("\t");
	//		Serial.println(imgRgbData[i][2]);
	//	}
	//	//配置rgb到屏幕
	//	led->clear();

	//	//32*8
	//	for ( int i = 0; i < 64; i++ )
	//	{
	//		led->drawPixel((i % 8)+12 , i / 8 , led->Color(imgRgbData[i][0], imgRgbData[i][1], imgRgbData[i][2]));
	//	}

	//	led->show();

	//}
	//led->clear();
	//for ( int i = 0; i < 32; i++ )
	//{
	//	led->drawPixel(i , 3 , led->Color(255 , 0 , 0));//r
	//}

	//for ( int i = 0; i < 32; i++ )
	//{
	//	led->drawPixel(i , 4 , led->Color(0 , 255 , 0));//g
	//}

	//for ( int i = 0; i < 32; i++ )
	//{
	//	led->drawPixel(i , 5 , led->Color(0 , 0 , 255));//b
	//}

	//for ( int i = 0; i < 32; i += 3 )
	//{
	//	led->drawPixel(i , 7 , rand() % 63488);
	//	led->drawPixel(i + 1 , 7 , rand() % 63488);
	//	led->drawPixel(i + 2 , 7 , rand() % 63488);
	//}
	//led->show();

	//delay(3000);
	//srand(millis());
	//led->clear();

	//for ( int i = 0; i < 64; i++ )
	//{
	//	for ( int j = 0; j < 3; j++ )
	//	{
	//		displayData[i * 3 + j] = rand() % 255;
	//	}

	//}

	//for ( int i = 0; i < 64; i++ )
	//{
	//	for ( int j = 0; j < 3; j++ )
	//	{
	//		led->drawPixel(i % 8 , i / 8 , displayData[i * 3 + j]);
	//	}

	//}
	//led->show();
	//server.handleClient();
}

void updata(AsyncWebServerRequest* request)
{
	
	upData = request->arg("imgData");
	//isUpData = true;
	//Serial.println(upData);

	//开始解析数据
	Serial.print("获取到的更新数据");
	Serial.println(upData);
	int lastIndex = 0;//上一个@的位置
	int nextIndex = 0;//下一个@的位置
	int nowIndex = 0;//当前找打了几个@
	for ( int i = 0; i < upData.length(); i++ )
	{
		if ( upData[i] == '@' )
		{
			if ( nowIndex >= 64 )
			{
				Serial.print("err:数据长度错误,代码:");
				Serial.println(nowIndex);
				request->send(404);
				return;
			}
			nextIndex = i;
			//剪切字符串
			String data_temp = upData.substring(lastIndex , nextIndex);
			//保存上一个字符串的位置
			lastIndex = i + 1;
			//Serial.println(data_temp);
			//提取数据
			int r , g , b;
			r = data_temp.substring(0 , data_temp.indexOf(",")).toInt();
			g = data_temp.substring(data_temp.indexOf(",") + 1 , data_temp.lastIndexOf(",")).toInt();
			b = data_temp.substring(data_temp.lastIndexOf(",") + 1).toInt();
			/*Serial.print(r);
			Serial.print("\t");
			Serial.print(g);
			Serial.print("\t");
			Serial.println(b);*/
			//放入数组
			imgRgbData[nowIndex][0] = r;
			imgRgbData[nowIndex][1] = g;
			imgRgbData[nowIndex][2] = b;

			nowIndex++;//更新当前的位置
		}
	}
	for ( int i = 0; i < 63; i++ )
	{
		Serial.print(imgRgbData[i][0]);
		Serial.print("\t");
		Serial.print(imgRgbData[i][1]);
		Serial.print("\t");
		Serial.println(imgRgbData[i][2]);
	}
	//配置rgb到屏幕
	led->clear();

	//32*8
	for ( int i = 0; i < 64; i++ )
	{
		led->drawPixel(( i % 8 ) + 12 , i / 8 , led->Color(imgRgbData[i][0] , imgRgbData[i][1] , imgRgbData[i][2]));
	}

	led->show();
	request->send(200);
}

// 处理用户浏览器的HTTP访问
void handleUserRequet(AsyncWebServerRequest* request)
{

	// 获取用户请求网址信息
	String webAddress = request->url();

	Serial.print("Not Found:");
	Serial.println(webAddress);


	if ( SPIFFS.exists(webAddress) )// 如果访问的文件可以在SPIFFS中找到
	{
		request->send(404 , "text/plain" , "404 Not Found");
	}
}


